using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using CPlatePrintSys.Domain.Models;
using CPlatePrintSys.DataAccess.Context;
using CPlatePrintSys.Infrastructure.Repositories;

namespace CPlatePrintSys.DataAccess.Repositories
{
    public class ShipRepository : IShipRepository
    {
        private readonly CPlateDbContext _context;
        public ShipRepository(CPlateDbContext context) { _context = context; }

        public async Task<List<MotherShip>> GetAllMotherShipsAsync()
            => await _context.MotherShips.Include(m => m.StreamShips).ToListAsync();

        public async Task<List<StreamShip>> GetStreamShipsByMotherIdAsync(int motherId)
            => await _context.StreamShips.Where(s => s.MotherShipId == motherId).ToListAsync();

        public async Task AddMotherShipAsync(MotherShip motherShip)
        {
            _context.MotherShips.Add(motherShip);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteMotherShipAsync(int id)
        {
            var entity = await _context.MotherShips.FindAsync(id);
            if (entity != null)
            {
                _context.MotherShips.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task AddStreamShipAsync(StreamShip streamShip)
        {
            _context.StreamShips.Add(streamShip);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteStreamShipAsync(int id)
        {
            var entity = await _context.StreamShips.FindAsync(id);
            if (entity != null)
            {
                _context.StreamShips.Remove(entity);
                await _context.SaveChangesAsync();
            }
        }

        public async Task UpdateStreamShipAsync(int streamShipId, int newMotherShipId)
        {
            var entity = await _context.StreamShips.FindAsync(streamShipId);
            if (entity != null)
            {
                entity.MotherShipId = newMotherShipId;
                await _context.SaveChangesAsync();
            }
        }

        public async Task<bool> MotherShipNoExistsAsync(string shipNo)
            => await _context.MotherShips.AnyAsync(m => m.ShipNo == shipNo);

        public async Task<bool> StreamShipNoExistsAsync(string shipNo)
            => await _context.StreamShips.AnyAsync(s => s.ShipNo == shipNo);

        public async Task<Dictionary<string, string>> GetStreamShipToMotherShipMapAsync()
        {
            // key: StreamShipNo, value: MotherShipNo
            var map = await (from s in _context.StreamShips
                             join m in _context.MotherShips on s.MotherShipId equals m.Id
                             select new { StreamShipNo = s.ShipNo, MotherShipNo = m.ShipNo }).ToListAsync();
            return map.ToDictionary(x => x.StreamShipNo, x => x.MotherShipNo);
        }

        public async Task<MotherShip> GetMotherShipByIdAsync(int id)
        {
            return await _context.MotherShips.FindAsync(id);
        }

        public async Task<StreamShip> GetStreamShipByIdAsync(int id)
        {
            return await _context.StreamShips.FindAsync(id);
        }

        public async Task UpdateMotherShipNoAsync(int id, string newShipNo)
        {
            var entity = await _context.MotherShips.FindAsync(id);
            if (entity != null)
            {
                entity.ShipNo = newShipNo;
                await _context.SaveChangesAsync();
            }
        }

        public async Task UpdateStreamShipNoAsync(int id, string newShipNo)
        {
            var entity = await _context.StreamShips.FindAsync(id);
            if (entity != null)
            {
                entity.ShipNo = newShipNo;
                await _context.SaveChangesAsync();
            }
        }
    }
} 